<?php

declare(strict_types=1);

namespace App\Controller;

use App\Models\WechatUser;
use App\Service\PaymentBusinessService;
use App\Service\QueueService;
use App\Service\WechatFactory;
use Carbon\Carbon;
use EasyWeChat\Kernel\Messages\Image;
use EasyWeChat\Kernel\Messages\Media;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\Codec\Json;
use Psr\Log\LoggerInterface;

/**
 * @Controller(prefix="/api/h5/v2/wechat")
 */
class WechatController extends AbstractController
{
    /**
     * @var LoggerInterface
     */
    protected $logger;

    /**
     * @Inject()
     * @var QueueService
     */
    protected $job;

    /**
     * @Inject()
     * @var WechatFactory
     */
    protected $wechatFactory;

    /**
     * @Inject()
     * @var PaymentBusinessService
     */
    protected $paymentBusinessService;

    public function __construct(LoggerFactory $loggerFactory)
    {
        $this->logger = $loggerFactory->get('log', 'default');
    }

    /**
     * 处理微信消息
     * @RequestMapping(path="/wechat", methods="get,post,head")
     */
    public function server(RequestInterface $request)
    {
        $app = $this->wechatFactory->officialAccount();

        $app->server->push(function ($msg) use (&$app) {
            $this->logger->info('接收微信消息: ' . Json::encode($msg));
            try {
                // 记录微信用户 (交互时间)
                if (isset($msg['FromUserName'])) {
                    WechatUser::query()->updateOrCreate(['openid' => $msg['FromUserName']], ['receive_last_message' => Carbon::now()]);
                }

                // 当用户发送数字时,活动编号,单独推送素材
                if (isset($msg['Content']) && is_numeric($msg['Content'])) {
                    $this->job->pushActivity($msg['Content'], $msg['FromUserName']);
                }

                if ($msg['MsgType'] === 'event') {
                    switch ($msg['EventKey']) {
                        case 'copywriting_received':
                            return '文案收到!';
                        case 'platform_introduction':
                            // 平台介绍
                            $app->customer_service
                                ->message(new Media('tHrIp7R_0QwWD7qZUmj3TVJzdgWS_QwXhXZo4kLIeh4', 'mpnews'))
                                ->to($msg['FromUserName'])
                                ->send();
                            break;
                        case 'newcomer_start':
                            // 新人起步
                            $app->customer_service
                                ->message(new Media('tHrIp7R_0QwWD7qZUmj3TSk4vS_zzNDL0UNLF_fcYE0', 'mpnews'))
                                ->to($msg['FromUserName'])
                                ->send();
                            break;
                        case 'into_the_material_group':
                            // 进素材群
                            $app->customer_service
                                ->message(new Image('sQEXkI0QHn_zMtnYyYecRMmorN3XpKWc-I79sFIO6YM'))
                                ->to($msg['FromUserName'])
                                ->send();
                            break;
                        case 'operation_notice':
                            // 运营须知
                            $app->customer_service
                                ->message(new Media('tHrIp7R_0QwWD7qZUmj3TQi2TzitHRoYrYQc3p5mt-8', 'mpnews'))
                                ->to($msg['FromUserName'])
                                ->send();
                            break;
                        case 'operating_material':
                            // 运营素材
                            $app->customer_service
                                ->message(new Media('tHrIp7R_0QwWD7qZUmj3TePVjmkPE1SL9ukb6e5GNwk', 'mpnews'))
                                ->to($msg['FromUserName'])
                                ->send();
                            break;
                    }
                }
            } catch (\Exception $e) {
                $this->logger->error(sprintf('推送活动素材发生错误: %s (%s[%d])', $e->getMessage(), $e->getFile(), $e->getLine()));
            }
        });

        return $app->server->serve()->getContent();
    }

    /**
     * @GetMapping(path="js-sdk-config")
     */
    public function jsSdkConfig()
    {
        $app = $this->wechatFactory->officialAccount();

        return $this->response->raw(
            $app
                ->jssdk
                ->setUrl($this->request->input('url', ''))
                ->buildConfig(
                    $this->request->input('js_api_list', []),
                    $this->request->input('debug', config('app_env') === 'dev'))
        );
    }

    /**
     * 给另外一个系统 access token, TODO 安全性
     * @GetMapping(path="a-t")
     */
    public function accessToken()
    {
        $app = $this->wechatFactory->officialAccount();

        return $this->response->json($app->access_token->getToken());
    }

    /**
     * 根据 Code 获取用户信息
     * @GetMapping(path="user-base")
     */
    public function getUserBaseByCode()
    {
        try {
            $app = $this->wechatFactory->officialAccount();
            $wxUser = $app->oauth->user($app->oauth->getAccessToken($this->request->input('code', '')));
        } catch (\Exception $e) {

        }

        return $this->response->json($wxUser ?? []);
    }
}
